
/**
 * Date:2019年6月4日下午4:11:01
 * Copyright (c) 2019, www.bwbroad.com All Rights Reserved.
 *
*/

package com.xue.im.client.core;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;

import javax.swing.ImageIcon;

import com.xue.im.client.ui.ChatDialog;
import com.xue.im.client.ui.LoginDialog;
import com.xue.im.client.ui.UserListDialog;
import com.xue.im.common.IMUtil;
import com.xue.im.common.IMUtil.MessageType;
import com.xue.im.common.vo.Message;
import com.xue.im.common.vo.User;

/**
 * Description: 客户端上下文，主要用于解耦IMClient和UI组件 <br/>
 * Date: 2019年6月4日 下午4:11:01 <br/>
 * 
 * @author xuejianxin
 */
public class IMClientContext {

	public static ImageIcon woman = new ImageIcon(IMClientContext.class.getResource("/head0.jpg"));
	public static ImageIcon man = new ImageIcon(IMClientContext.class.getResource("/head1.jpg"));
	public static ImageIcon client = new ImageIcon(IMClientContext.class.getResource("/client16_5.png"));

	private BlockingQueue<Message> sendList;// 消息发送队列
	private BlockingQueue<Message> reciveList;// 消息接收队列
	private IMClient imClient;// 客户端
	private volatile boolean isStart = false;// 是否启动
	private User currentUser = new User();// 当前用户
	private Map<String, Queue<String>> userMessage = new HashMap<>();// 用户消息列表
	private Map<String, User> userMap = new HashMap<>();// 用户id与用户映射

	private final static class IMClientContextHolder {
		private static IMClientContext instance = new IMClientContext();
	}

	public static IMClientContext get() {
		return IMClientContextHolder.instance;
	}

	private IMClientContext() {

	}

	// 启动客户端
	public IMClientContext startClient(String ip, int port) {
		if (!isStart) {
			sendList = new ArrayBlockingQueue<>(10);
			reciveList = new ArrayBlockingQueue<>(100);
			imClient = new IMClient(ip, port);
			startSend();
			startRecive();
			isStart = true;
			imClient.submit(() -> {
				try {
					// 这是一个阻塞方法
					imClient.connect();
				} catch (Exception e) {
					e.printStackTrace();
				}
			});
		}
		return this;
	}

	// 销毁线程池
	public void shutdown() {
		if (null != imClient) {
			imClient.shutdown();
			isStart = false;
		}
	}

	// 开始接收信息
	@SuppressWarnings("unchecked")
	private void startRecive() {
		// 处理接收信息
		imClient.submit(() -> {
			while (true) {
				Message m;
				try {
					m = reciveList.poll(10, TimeUnit.SECONDS);
					if (null != m) {
						// System.out.println("<<<<<<<<<--------------" + m);
						byte t = m.getHeader().getType();
						if (t == MessageType.TEXT_RESP.value()) {// 文本消息
							String body = m.getBody().toString();
							IMClientContext.get().addMessage(m.getSender(), body, true);
							UserListDialog.getInstance().refreshUserList();// 刷新统计信息
							ChatDialog.getInstance().refreshMessage();// 刷新用户列表
							// 保存消息到数据库
						} else if (t == MessageType.LOGIN_RESP.value()) {// 登录响应
							User u = (User) m.getBody();// 设置当前用户
							if (u.getStatus() == IMUtil.USER_STATUS_ONLINE) {// 登录成功
								// 销毁登录框
								LoginDialog.getInstance().dispose();
								// 用户列表对话框显示
								UserListDialog.getInstance().setVisible(true);
								// UserListDialog.getInstance().setAlwaysOnTop(true);
								currentUser.setStatus(IMUtil.USER_STATUS_ONLINE);
								currentUser.setUsername(u.getUsername());
								currentUser.setSex(u.getSex());
								UserListDialog.getInstance().refreshUser(currentUser);
								// 发送请求获取用户列表
								sendMessage(IMUtil.buildMessage(MessageType.USERLIST_REQ));
							} else {
								LoginDialog.getInstance().refreshMsg("登录失败," + IMUtil.getUserStatusMsg(u.getStatus()));
								shutdown();
							}
						} else if (t == MessageType.USERLIST_RESP.value()) {// 用户列表
							List<User> list = (List<User>) m.getBody();
							for (User u : list) {
								userMap.put(u.getUserid(), u);
							}
							UserListDialog.getInstance().refreshUserList(list);
						} else if (t == MessageType.USER_ONLIE_RESP.value()) {// 用户上线下线通知
							User u = (User) m.getBody();
							User uLocal = userMap.get(u.getUserid());
							if (null != uLocal) {
								uLocal.setStatus(u.getStatus());// 变更
								uLocal.setIp(u.getIp());// ip变更
								UserListDialog.getInstance().refreshUserList();
							}
						} else if (t == MessageType.FILE_RESP.value()) {
							String fileName = (String) m.getOption("fileName");
							System.out.println("收到文件------------------------" + fileName);
							byte[] fileArr = (byte[]) m.getBody();
							String filePath = IMUtil.getFileDir() + IMUtil.getNow1() + fileName;
							IMUtil.toFile(filePath, fileArr);
							String body = String.format("收到一个文件,保存地址:\n  %s", filePath);
							body = IMUtil.formatMessage(IMClientContext.get().getCurrentUser().getUsername(), body);
							IMClientContext.get().addMessage(m.getSender(), body, true);
						}

					}
				} catch (InterruptedException e) {
					// 在收到关闭信号时退出循环
					break;
				}

			}
		});

	}

	// 开始发送信息
	private void startSend() {
		// 处理发送信息
		imClient.submit(() -> {
			while (true) {
				Message m;
				try {
					m = sendList.poll(10, TimeUnit.SECONDS);
					// System.out.println(">>>>>>>>>:" + m);
					if (null != m && null != imClient) {
						imClient.sendMessage(m);
					}
				} catch (InterruptedException e) {
					// 在收到关闭信号时退出循环
					break;
				}
			}
		});
	}

	// 发送信息
	public IMClientContext sendMessage(Message message) {
		try {
			sendList.put(message);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		return this;
	}

	// 发送信息
	public IMClientContext sendMessage(String message) {
		return sendMessage(IMUtil.buildMessage(MessageType.TEXT_REQ, message));
	}

	// 发送信息
	public IMClientContext sendMessage(User receiver, String message) {
		Message m = IMUtil.buildMessage(MessageType.TEXT_REQ, currentUser, receiver, message);
		return sendMessage(m);
	}

	// 接收信息
	public void receiveMessage(Message message) {
		try {
			reciveList.put(message);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	public IMClientContext setPassword(String password) {
		this.currentUser.setPassword(password);
		return this;
	}

	public IMClientContext setUserid(String userid) {
		this.currentUser.setUserid(userid);
		return this;
	}

	// 获取当前用户
	public User getCurrentUser() {
		return currentUser;
	}

	// 设置当前用户
	public IMClientContext setCurrentUser(User currentUser) {
		this.currentUser = currentUser;
		return this;
	}

	// 添加消息到对应的用户消息列表
	public void addMessage(String userid, String msg, boolean addMsgCount) {
		if (addMsgCount) {
			userMap.get(userid).addMsgCount();
		}
		Queue<String> msgList = userMessage.get(userid);
		if (null == msgList) {
			msgList = new LinkedList<>();
			userMessage.put(userid, msgList);
		}
		if (msgList.size() >= 100) {
			msgList.poll();
		}
		msgList.offer(msg);
	}

	// 获取用户消息列表
	public Queue<String> getMessage(String userid) {
		return userMessage.get(userid);
	}

}
